package com.zdp.seckill.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zdp.seckill.common.exception.BusinessException;
import com.zdp.seckill.common.validator.ValidationResult;
import com.zdp.seckill.common.validator.ValidatorImpl;
import com.zdp.seckill.mapper.ItemMapper;
import com.zdp.seckill.mapper.ItemStockMapper;
import com.zdp.seckill.mapper.ItemStockMapperCustom;
import com.zdp.seckill.pojo.Item;
import com.zdp.seckill.pojo.ItemStock;
import com.zdp.seckill.pojo.vo.ItemModel;
import com.zdp.seckill.pojo.vo.PromModel;
import com.zdp.seckill.service.ItemService;
import com.zdp.seckill.service.PromoService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sesshomaru
 * @date 2021/6/18 23:39
 */
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ValidatorImpl validator;

    @Autowired
    private ItemMapper itemMapper;

    @Autowired
    private ItemStockMapper itemStockMapper;

    @Autowired
    private ItemStockMapperCustom itemStockMapperCustom;

    @Autowired
    private PromoService promoService;

    @Transactional
    @Override
    public void increaseSales(Integer itemId, Integer amount) {
        itemMapper.increaseSales(amount, itemId);
    }

    @Transactional
    @Override
    public boolean decreaseStock(Integer itemId, Integer amount) {
        // 返回影响的条目数
        int affectedRow = itemStockMapperCustom.decreaseStock(itemId, amount);
        return affectedRow > 0;
    }

    @Transactional
    @Override
    public ItemModel createItem(ItemModel itemModel) {
        // 校验入参
        ValidationResult validationResult = validator.validate(itemModel);
        if (validationResult.isHasErrors()) {
            throw new BusinessException(validationResult.getErrMsg());
        }
        // 转换对象
        Item item = convertItemFromItemModel(itemModel);
        ItemStock itemStock = convertItemStockFromItemModel(itemModel);

        // 写入数据库
        // 商品
        itemMapper.insert(item);
        Integer itemId = item.getId();
        itemStock.setItemId(itemId);
        // 商品库存
        itemStockMapper.insert(itemStock);

        // 返回创建对象
        return this.getItemById(itemId);
    }

    @Override
    public List<ItemModel> listItem() {
        List<Item> itemList = itemMapper.selectList(new QueryWrapper<>());
        List<ItemModel> itemModelList = itemList.stream().map(item -> {
            QueryWrapper<ItemStock> itemStockQueryWrapper = new QueryWrapper<>();
            itemStockQueryWrapper.eq("item_id", item.getId());
            ItemStock itemStock = itemStockMapper.selectOne(itemStockQueryWrapper);
            ItemModel itemModel = this.convertModelFromDataObject(item, itemStock);
            return itemModel;
        }).collect(Collectors.toList());
        return itemModelList;
    }

    @Override
    public ItemModel getItemById(Integer id) {
        Item item = itemMapper.selectById(id);
        if (item == null) {
            return null;
        }
        QueryWrapper<ItemStock> itemStockQueryWrapper = new QueryWrapper<>();
        itemStockQueryWrapper.eq("item_id", id);
        ItemStock itemStock = itemStockMapper.selectOne(itemStockQueryWrapper);
        if (itemStock == null) {
            return null;
        }
        ItemModel itemModel = convertModelFromDataObject(item, itemStock);
        PromModel promModel = promoService.getPromModelByItemId(itemModel.getId());
        // 存在promModel并且活动必须是未开始或者进行中的才可以设置，已经结束的就不应该在添加这个秒杀商品的对象
        if (promModel != null && promModel.getStatus().intValue() != 3) {
            itemModel.setPromoModel(promModel);
        }
        return itemModel;
    }

    private ItemModel convertModelFromDataObject(Item item, ItemStock itemStock) {
        ItemModel itemModel = new ItemModel();
        BeanUtils.copyProperties(item, itemModel);
        itemModel.setPrice(new BigDecimal(item.getPrice()));
        itemModel.setStock(itemStock.getStock());
        return itemModel;
    }

    private Item convertItemFromItemModel(ItemModel itemModel) {
        if (itemModel == null) {
            return null;
        }
        Item item = new Item();
        BeanUtils.copyProperties(itemModel, item);
        item.setPrice(itemModel.getPrice().doubleValue());
        return item;
    }

    private ItemStock convertItemStockFromItemModel(ItemModel itemModel){
        if (itemModel == null) {
            return null;
        }
        ItemStock itemStock = new ItemStock();
        BeanUtils.copyProperties(itemModel, itemStock);
        return itemStock;
    }
}
